package com.pipi.sso.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.pipi.sso.core.exception.DormServiceException;
import com.pipi.sso.core.service.DormitoryBuildingService;
import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.enums.DormErrorCodeEnum;
import com.pipi.sso.core.model.DormitoryBuildingBO;
import com.pipi.sso.core.util.BeanUtils;
import com.pipi.sso.dao.manager.DormitoryAllocationManager;
import com.pipi.sso.dao.manager.DormitoryBuildingManager;
import com.pipi.sso.dao.model.DormitoryBuildingDO;
import com.pipi.sso.dao.query.DormitoryAllocationQuery;
import com.pipi.sso.dao.query.DormitoryBuildingQuery;
import com.pipi.sso.dao.support.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 *
 * @Package com.pipi.sso.core.service.impl
 * @date: 2019/4/12 8:38 PM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Service
@Slf4j
public class DormitoryBuildingServiceImpl implements DormitoryBuildingService {

    @Resource
    private DormitoryBuildingManager dormitoryBuildingManager;

    @Resource
    private DormitoryAllocationManager dormitoryAllocationManager;

    @Override
    public PageResult<DormitoryBuildingBO> queryByPaged(DormitoryBuildingBO dormitoryBuildingBO) {
        DormitoryBuildingQuery query = buildQuery(dormitoryBuildingBO);
        query.setPageNo(dormitoryBuildingBO.getPage());
        query.setPageSize(dormitoryBuildingBO.getLimit());
        try {
            PageResult<DormitoryBuildingDO> pageResult = dormitoryBuildingManager.selectByQueryWithPage(query);
            if (CollectionUtils.isEmpty(pageResult.getResult())) {
                return PageResult.createPageResult();
            }
            List<DormitoryBuildingBO> dormitoryBuildingBOS = buildingBOS(pageResult.getResult());
            return PageResult.createPageResult(dormitoryBuildingBOS, pageResult.getPageInfo());
        } catch (Exception e) {
            log.error("查询宿舍楼失败！dormitoryBuildingBO is {}", JSON.toJSONString(dormitoryBuildingBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_DORMITORY_BUILDING_FAIL);
        }
    }

    @Override
    public List<DormitoryBuildingBO> queryNoPaged(DormitoryBuildingBO dormitoryBuildingBO) {
        DormitoryBuildingQuery query = buildQuery(dormitoryBuildingBO);
        try {
            List<DormitoryBuildingDO> dormitoryBuildingDOS = dormitoryBuildingManager.selectByQuery(query);
            if (CollectionUtils.isEmpty(dormitoryBuildingDOS)) {
                return Lists.newArrayList();
            }
            return buildingBOS(dormitoryBuildingDOS);
        } catch (Exception e) {
            log.error("查询宿舍楼失败！dormitoryBuildingBO is {}", JSON.toJSONString(dormitoryBuildingBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_DORMITORY_BUILDING_FAIL);
        }
    }

    @Override
    public void addDormitoryBuilding(DormitoryBuildingBO dormitoryBuildingBO) {
        try {
            DormitoryBuildingQuery query = new DormitoryBuildingQuery();
            query.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode())
                    .andBuildingNoEqualTo(dormitoryBuildingBO.getBuildingNo());
            List<DormitoryBuildingDO> dormitoryBuildingDOS = dormitoryBuildingManager.
                    selectByQuery(query);
            if (CollectionUtils.isNotEmpty(dormitoryBuildingDOS)) {
                log.error("不可重复添加宿舍楼! dormitoryBuildingBO is {}",
                        JSON.toJSONString(dormitoryBuildingBO));
                throw new DormServiceException(DormErrorCodeEnum.PARAM_ERROR.getErrCode(),
                        "不可重复添加宿舍楼");
            }
            DormitoryBuildingDO dormitoryBuildingDO = BeanUtils.createCloneBean
                    (dormitoryBuildingBO, DormitoryBuildingDO.class);
            dormitoryBuildingDO.setIsDeleted(CommonStatusEnum.NO.getCode());
            dormitoryBuildingManager.insertSelective(dormitoryBuildingDO);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("添加宿舍楼失败！dormitoryBuildingBO is {}",
                    JSON.toJSONString(dormitoryBuildingBO), e);
            throw new DormServiceException(DormErrorCodeEnum.ADD_DORMITORY_BUILDING_FAIL);
        }
    }

    @Override
    public void updateDormitoryBuilding(DormitoryBuildingBO dormitoryBuildingBO) {
        try {
            DormitoryBuildingDO dormitoryBuildingDO = BeanUtils.createCloneBean(dormitoryBuildingBO, DormitoryBuildingDO.class);
            dormitoryBuildingManager.updateByPrimaryKeySelective(dormitoryBuildingDO);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新宿舍楼失败！dormitoryBuildingBO", JSON.toJSONString(dormitoryBuildingBO), e);
            throw new DormServiceException(DormErrorCodeEnum.UPDATE_DORMITORY_BUILDING_FAIL);
        }
    }

    @Override
    public void deleteDormitoryBuilding(List<Long> dormitoryBuildingIds) {
        try {
            DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
            dormitoryAllocationQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode()).andBuildingIdIn(dormitoryBuildingIds);
            int count = dormitoryAllocationManager.countByQuery(dormitoryAllocationQuery);
            if (count > 0) {
                log.error("不可删除有学生入住的楼栋！");
                throw new DormServiceException(DormErrorCodeEnum.DELETE_DORMITORY_BUILDING_FAIL.getErrCode(), "不可删除有学生入住的楼栋");
            }
            DormitoryBuildingQuery dormitoryBuildingQuery = new DormitoryBuildingQuery();
            dormitoryBuildingQuery.createCriteria().andDormitoryBuildingIdIn(dormitoryBuildingIds);

            DormitoryBuildingDO dormitoryBuildingDO = new DormitoryBuildingDO();
            dormitoryBuildingDO.setIsDeleted(CommonStatusEnum.YES.getCode());
            dormitoryBuildingManager.updateByQuery(dormitoryBuildingDO, dormitoryBuildingQuery);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除宿舍楼失败！dormitoryBuildingIds is {}", JSON.toJSONString(dormitoryBuildingIds));
            throw new DormServiceException(DormErrorCodeEnum.DELETE_DORMITORY_BUILDING_FAIL);
        }
    }

    private DormitoryBuildingQuery buildQuery(DormitoryBuildingBO dormitoryBuildingBO) {
        DormitoryBuildingQuery query = new DormitoryBuildingQuery();
        query.setOrderByClause("gmt_create desc");
        DormitoryBuildingQuery.Criteria criteria = query.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
        if (null != dormitoryBuildingBO) {
            if (Objects.nonNull(dormitoryBuildingBO.getDormitoryBuildingId())) {
                criteria.andDormitoryBuildingIdEqualTo(dormitoryBuildingBO.getDormitoryBuildingId());
            }
            if (StringUtils.isNotBlank(dormitoryBuildingBO.getBuildingNo())) {
                criteria.andBuildingNoEqualTo(dormitoryBuildingBO.getBuildingNo());
            }
            if (StringUtils.isNotBlank(dormitoryBuildingBO.getHandler())) {
                criteria.andHandlerLike("%" + dormitoryBuildingBO.getHandler() + "%");
            }
            if (Objects.nonNull(dormitoryBuildingBO.getGender())) {
                criteria.andGenderEqualTo(dormitoryBuildingBO.getGender());
            }
        }
        return query;

    }

    private List<DormitoryBuildingBO> buildingBOS(List<DormitoryBuildingDO> dormitoryBuildingDOS) {
        if (CollectionUtils.isEmpty(dormitoryBuildingDOS)) {
            return null;
        }
        return dormitoryBuildingDOS.stream().map(this::buildingBO).collect(Collectors.toList());
    }

    private DormitoryBuildingBO buildingBO(DormitoryBuildingDO dormitoryBuildingDO) {
        if (null == dormitoryBuildingDO) {
            return null;
        }
        DormitoryBuildingBO dormitoryBuildingBO = BeanUtils.createCloneBean(dormitoryBuildingDO, DormitoryBuildingBO.class);
        DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
        dormitoryAllocationQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode()).andBuildingIdEqualTo(dormitoryBuildingBO.getDormitoryBuildingId());
        int count = dormitoryAllocationManager.countByQuery(dormitoryAllocationQuery);
        dormitoryBuildingBO.setCheckInNumber(count);
        dormitoryBuildingBO.setGenderDesc(CommonStatusEnum.getGenderDescByCode(dormitoryBuildingBO.getGender()));
        return dormitoryBuildingBO;
    }
}
